import { ProTable, type ProColumns } from '@/components/Pro';
import { parseArray } from '@/pages/Statistics/Battery/utils';
import { dateFormatterMap, netRequestMap, rowToColumns } from '@/pages/Statistics/Net/CommonMap';
import { TreeNode } from '@/pages/Statistics/PowerGeneration/help';
import { getDeviceCascader } from '@/utils/formatterTree';
import { useModel } from '@@/exports';
import { useIntl } from '@umijs/max';
import dayjs, { Dayjs } from 'dayjs';
import _ from 'lodash';
import moment from 'moment';
import React, { useEffect, useRef, useState } from 'react';
import './Common.less';

type IProps = {
  dateType: string;
  changeReportData: (data: any) => void;
};
type areaColumnsType = {
  title: string;
  dataIndex: string;
  key: string;
  hideInSearch: boolean;
};

const NetReport: React.FC<IProps> = (props) => {
  const intl = useIntl();
  const sumColumnsMap = {
    date: intl.formatMessage({ id: 'statistics.common.daySum' }),
    month: intl.formatMessage({ id: 'statistics.common.monthSum' }),
    year: intl.formatMessage({ id: 'statistics.common.yearSum' }),
  };
  const tableColumnsMap = new Map<string, string>([
    ['pocOnEnergy', `${intl.formatMessage({ id: 'batteryVoltage.safe.onGrid' })}(kWh)`],
    ['pocOffEnergy', `${intl.formatMessage({ id: 'batteryVoltage.safe.offGrid' })}(kWh)`],
    ['chargeTimes', `${intl.formatMessage({ id: 'statistics.work.chargeTimes' })}`],
    ['dischargeTimes', `${intl.formatMessage({ id: 'statistics.work.dischargeTimes' })}`],
  ]);
  const { changeReportData, dateType } = props;
  const { initialState } = useModel('@@initialState');
  const [summary, setSummary] = useState<any[]>([]);
  const [isEmpty, changeIsEmpty] = useState(false);
  const deviceTree = useRef(null);
  const [deviceVal, setDeviceVal] = useState();
  const [isPartitionQuery, setIsPartitionQuery] = useState(false);
  const [areaId, setAreaId] = useState<string[] | number[] | null>(null);
  const [dateVal, setDateVal] = useState(dayjs());
  const tableRef = useRef(null);
  const [columnsState, setColumnsState] = useState({});
  const selectedType = useRef(null);
  /**
   * 获得禁用列表
   * @param Nodes
   */
  const setDisabled = (Nodes: TreeNode[]): TreeNode[] => {
    return Nodes.map((node) => {
      const newNode: TreeNode = {
        ...node,
        disabled: selectedType.current === null ? false : node.nodeType !== selectedType.current,
      };
      if (newNode.subDevices) {
        newNode.subDevices = setDisabled(newNode.subDevices);
      }
      return newNode;
    });
  };
  /**
   * 获得对应的columns
   * @param keys
   */
  const getAreaColumns = (keys: string[]): areaColumnsType[] => {
    return keys.map((item: string) => {
      const nameArr = item.split('_');
      return {
        title: `${nameArr[0]}_${tableColumnsMap.get(nameArr[1])}`,
        dataIndex: item,
        key: item,
        hideInSearch: true,
      };
    });
  };
  useEffect(() => {
    if (initialState?.isArea) {
      getDeviceCascader(false, 2).then((res) => {
        setDeviceVal(res[0].uniqueId);
        selectedType.current = 'ROOT';
        deviceTree.current = setDisabled([res[0]]);
      });
    }
  }, []);

  const columns: ProColumns[] = [
    {
      valueType: 'index',
      title: intl.formatMessage({ id: 'batteryVoltage.no' }),
      width: 60,
    },
    {
      title: intl.formatMessage({ id: 'statistics.common.period' }),
      dataIndex: 'timeRange',
      hideInSearch: true,
      hideInTable: dateType !== 'date',
      render: (_, record) => {
        return (
          <span>
            {record.startTime}-{record.endTime}
          </span>
        );
      },
    },
    {
      title: intl.formatMessage({ id: 'data.time' }),
      dataIndex: 'date',
      hideInTable: dateType === 'date',
      hideInSearch: true,
      valueType: 'date',
      render: (_, record) => {
        return <span>{record.date}</span>;
      },
    },
    {
      title: intl.formatMessage({ id: 'statistics.income.select' }),
      dataIndex: 'date',
      hideInTable: true,
      valueType: 'date',
      initialValue: dayjs(),
      fieldProps: {
        picker: dateType,
        format: dateFormatterMap.get(dateType),
        value: dateVal,
        allowClear: false,
        onChange: (value: Dayjs, dateString: string) => {
          changeReportData({
            date: dateString,
            areaIdList: areaId,
            unit: dateType,
            stationId: initialState?.stationId,
            codes: isPartitionQuery ? '' : areaId,
            pageSize: isPartitionQuery ? 20 * areaId.length : 20,
          });
          setDateVal(value);
        },
        disabledDate: (current) => {
          return current && current > moment().endOf(dateType === 'date' ? 'day' : dateType);
        },
      },
    },
    // 分区维度模块
    {
      title: intl.formatMessage({ id: 'statistics.work.dimensions' }),
      dataIndex: 'codes',
      hideInTable: true,
      hideInSearch: !initialState?.isArea,
      key: 'codes',
      valueType: 'treeSelect',
      fieldProps: {
        maxCount: 100,
        maxTagCount: 'responsive',
        multiple: true,
        value: deviceVal,
        showSearch: true,
        treeData: deviceTree?.current,
        fieldNames: {
          label: 'deviceName',
          value: 'uniqueId',
          children: 'subDevices',
        },
        onSelect: function (...args) {
          let selectOptions = args[1];
          if (selectedType.current === null && selectOptions?.nodeType) {
            selectedType.current = selectOptions?.nodeType;
          }
          // setDeviceTree(setDisabled([deviceTree[0]]));
          deviceTree.current = setDisabled([deviceTree?.current[0]]);
        },
        onChange: function (...args) {
          setDeviceVal(args[0]);
          let selectedOptions = args[1];
          if (!selectedOptions.length) {
            //清除后不再做相应限制
            selectedType.current = null;
            // setDeviceTree(setDisabled([deviceTree[0]]));
            deviceTree.current = setDisabled([deviceTree?.current[0]]);
          }
          let hasAreaNode: boolean = false;
          const ans = parseArray(args[0]);
          if (ans.nodeType.length) {
            hasAreaNode = ans.nodeType.some((item: string) => {
              return item === 'AREA';
            });
          }
          setIsPartitionQuery(hasAreaNode);
          setAreaId(ans.id);
          changeReportData({
            date: dateVal.format(dateFormatterMap.get(dateType)),
            unit: dateType,
            areaIdList: ans.id,
            stationId: initialState?.stationId,
            codes: isPartitionQuery ? '' : areaId,
            pageSize: isPartitionQuery ? 20 * ans.id.length : 20,
          });
        },
      },
    },
  ];
  const stationColumns = [
    {
      title: `${intl.formatMessage({ id: 'batteryVoltage.safe.onGrid' })}(kWh)`,
      dataIndex: 'pocOnEnergy',
      hideInSearch: true,
    },
    {
      title: `${intl.formatMessage({ id: 'batteryVoltage.safe.offGrid' })}(kWh)`,
      dataIndex: 'pocOffEnergy',
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({ id: 'statistics.work.chargeTimes' }),
      dataIndex: 'chargeTimes',
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({ id: 'statistics.work.dischargeTimes' }),
      dataIndex: 'dischargeTimes',
      hideInSearch: true,
    },
  ];
  const getDayTimeRange = (arr) => {
    return arr.map((item) => {
      return {
        ...item,
        date: item.startTime + '-' + item.endTime,
      };
    });
  };
  const [getColumns, setGetColumns] = useState(columns);
  const [elseColumns, setElseColumns] = useState(stationColumns);
  useEffect(() => {
    setGetColumns([...columns, ...elseColumns]);
  }, [dateVal, deviceVal]);
  const renderSummary = () => {
    return (
      <ProTable.Summary.Row>
        {columnsState['index']?.show !== false && (
          <ProTable.Summary.Cell index={0}>{sumColumnsMap[props.dateType]}</ProTable.Summary.Cell>
        )}
        {columnsState['date']?.show !== false && (
          <ProTable.Summary.Cell index={1}></ProTable.Summary.Cell>
        )}
        {/*{columnsState['pocOnEnergy']?.show !== false && (*/}
        {/*  <ProTable.Summary.Cell index={2}>{total.pocOnEnergy}</ProTable.Summary.Cell>*/}
        {/*)}*/}
        {/*{columnsState['pocOffEnergy']?.show !== false && (*/}
        {/*  <ProTable.Summary.Cell index={3}>{total.pocOffEnergy}</ProTable.Summary.Cell>*/}
        {/*)}*/}
        {/*{columnsState['chargeTimes']?.show !== false && (*/}
        {/*  <ProTable.Summary.Cell index={4}>{total.chargeTimes}</ProTable.Summary.Cell>*/}
        {/*)}*/}
        {/*{columnsState['dischargeTimes']?.show !== false && (*/}
        {/*  <ProTable.Summary.Cell index={5}>{total.dischargeTimes}</ProTable.Summary.Cell>*/}
        {/*)}*/}
        {summary
          .flatMap((item, summaryIndex) => [
            { key: `totalPocOnGridEnergy${summaryIndex + 1}`, value: item.totalPocOnGridEnergy },
            { key: `totalPocOffGridEnergy${summaryIndex + 1}`, value: item.totalPocOffGridEnergy },
            { key: `totalChargeTime${summaryIndex + 1}`, value: item.totalChargeTime },
            { key: `totalDischargeTime${summaryIndex + 1}`, value: item.totalDischargeTime },
          ])
          .map(
            (item, index) =>
              columnsState[item.key]?.show !== false && (
                <ProTable.Summary.Cell key={index} index={index + 3}>
                  {item.value}
                </ProTable.Summary.Cell>
              ),
          )}
      </ProTable.Summary.Row>
    );
  };

  return (
    <>
      <ProTable
        actionRef={tableRef}
        headerTitle=" "
        style={{ position: 'relative', zIndex: '10' }}
        columns={getColumns}
        rowKey={'pageIndex'}
        params={{
          stationId: initialState?.stationId,
        }}
        onReset={() => {
          tableRef?.current?.reset();
          if (initialState?.isArea) {
            setDeviceVal(deviceTree?.current[0]?.uniqueId);
            selectedType.current = 'ROOT';
            deviceTree.current = setDisabled([deviceTree?.current[0]]);
            setAreaId([]);
            setIsPartitionQuery(false);
          }
          setDateVal(dayjs());
          changeReportData({
            date: dayjs().format(dateFormatterMap.get(dateType)),
            areaIdList: [],
            unit: dateType,
            stationId: initialState?.stationId,
            codes: '',
            pageSize: 20,
          });
        }}
        search={{
          className: 'searchPosInline',
        }}
        toolbar={{
          className: 'toobalrZindex',
          actions: [
            // eslint-disable-next-line react/button-has-type
          ],
        }}
        request={async (values) => {
          const params = {
            ...values,
            date: dayjs(dateVal).format(dateFormatterMap.get(dateType)),
            stationId: initialState?.stationId,
            areaIdList: isPartitionQuery ? areaId : null,
            codes: isPartitionQuery ? '' : areaId,
            pageSize: isPartitionQuery ? 20 * areaId.length : 20,
          };
          const res = await netRequestMap[dateType](params);
          const forRes = rowToColumns(
            dateType === 'date' ? getDayTimeRange(res.data.page.records) : res.data.page.records,
            dateType === 'date',
          );
          const keys = _.slice(Object.keys(forRes[0]), dateType === 'date' ? 6 : 4);
          if (isPartitionQuery) {
            setGetColumns([...columns, ...getAreaColumns(keys)]);
            setElseColumns(getAreaColumns(keys));
          } else {
            setGetColumns([...columns, ...stationColumns]);
            setElseColumns(stationColumns);
          }
          if (res.success) {
            changeIsEmpty(res?.data.page.total === '0');

            setSummary(
              isPartitionQuery
                ? res.data.total
                : [
                    {
                      totalPocOffGridEnergy: res?.data?.totalPocOffGridEnergy,
                      totalPocOnGridEnergy: res?.data?.totalPocOnGridEnergy,
                      totalChargeTime: res?.data?.totalChargeTime,
                      totalDischargeTime: res?.data?.totalDischargeTime,
                    },
                  ],
            );
            return {
              data: isPartitionQuery ? forRes : res.data.page.records,
              success: res.success,
              total: isPartitionQuery
                ? Number(res?.data?.page?.total) / areaId.length
                : res?.data.page.total,
            };
          }
        }}
        columnsState={{
          value: columnsState,
          onChange: setColumnsState,
        }}
        summary={() => !isEmpty && renderSummary()}
      ></ProTable>
    </>
  );
};

export default NetReport;
